package com.example;

import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Lab1：JDK8 Stream的使用，包括以下API
 *
 * @author Holinc
 * @date 2023/3/21 20:29
 */
public class Lab1 {

    /**
     * filter
     * map
     * mapToInt
     * mapToLong
     * mapToDouble
     * flatMap
     * distinct
     * sorted
     * limit
     * skip
     * forEach
     * collect
     * min
     * max
     * count
     * anyMatch
     * allMatch
     * noneMatch
     * findFirst
     * findAny
     * of
     *
     * @param args
     */
    public static void main(String[] args) {
        List<Integer> integerList = Arrays.asList(1, 23, 4, 54, 623, 2, 6, 345, 23, 8, 56, 435, 234, 234, 234, 4);
        integerList.forEach(item -> System.out.print(item + " "));
        System.out.println();

        // filter 过滤大于100的数据
        List<Integer> filterList = integerList.stream().filter(f -> f > 100).collect(Collectors.toList());
        filterList.forEach(item -> System.out.print(item + " "));
        System.out.println();

        List<Integer> limitList = filterList.stream().skip(2).limit(2).collect(Collectors.toList());
        limitList.forEach(item -> System.out.print(item + " "));
        System.out.println();

        // map filterList数据加10
        List<Integer> mapList = filterList.stream().map(item -> item + 10).collect(Collectors.toList());
        mapList.forEach(item -> System.out.print(item + " "));
        System.out.println();

        // distinct mapList去重
        List<Integer> distinctList = mapList.stream().distinct().collect(Collectors.toList());
        distinctList.forEach(item -> System.out.print(item + " "));
        System.out.println();

        List<Object> distinctList2 = Stream.of(mapList.toArray()).distinct().collect(Collectors.toList());
        distinctList2.forEach(item -> System.out.print(item + " "));
        System.out.println();

        long count = distinctList.stream().count();
        System.out.println(count);

        Optional<Integer> minOpt = distinctList.stream().min(Integer::compareTo);
        if (minOpt.isPresent()) {
            System.out.println(minOpt.get());
        }

//        Optional<Integer> minOpt2 = distinctList.stream().min((x, y) -> x.compareTo(y));
//        if (minOpt2.isPresent()) {
//            System.out.println(minOpt2.get());
//        }

        Optional<Integer> firstOpt = distinctList.stream().findFirst();
        if (firstOpt.isPresent()) {
            System.out.println(firstOpt.get());
        }

        boolean anyMatch = distinctList.stream().anyMatch(item -> item > 500);
        System.out.println(anyMatch);

        boolean anyMatch2 = distinctList.stream().anyMatch(item -> item < 0);
        System.out.println(anyMatch2);

        boolean allMatch = distinctList.stream().allMatch(item -> item > 100);
        System.out.println(allMatch);

        boolean allMatch2 = distinctList.stream().allMatch(item -> item > 1000);
        System.out.println(allMatch2);

        boolean noneMatch = distinctList.stream().noneMatch(item -> item > 100);
        System.out.println(noneMatch);

        // '!Stream.anyMatch(...)' can be replaced with 'noneMatch()'
        boolean noneMatch2 = !distinctList.stream().anyMatch(item -> item > 100);
        System.out.println(noneMatch2);


        // flatMap、Map的使用
        List<String> strings = Arrays.asList("hello", "world", "java");

        List<Integer> collect = strings.stream().flatMap(e ->
                Stream.of(e.length())
        ).collect(Collectors.toList());

        System.out.println(collect);

        List<Integer> collect1 = strings.stream().map(String::length).collect(Collectors.toList());
        System.out.println(collect1);

        Parent parent = new Parent();
        parent.setChildren(Arrays.asList(new Child(), new Child(), new Child()));
        List<Parent> parentsList = Arrays.asList(new Parent(), new Parent(), new Parent());

        List<Child> collect2 = new ArrayList<>();
        for (Parent p : parentsList) {
            for (Child child : p.getChildren()) {
                collect2.add(child);
            }
        }

        List<Child> collect3 = parentsList.stream().flatMap(p -> p.getChildren().stream()).collect(Collectors.toList());


//        <R> Stream<R> map(Function<? super T, ? extends R> mapper);
//        <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

    }


    @Data
    static class Parent {
        private String pName;
        private List<Child> children;
    }

    @Data
    static class Child{
        private String cName;
    }
}
